#include "fxcc/core/graph/opengl3/GlfwApp.h"
#include "fxcc/core/graph/opengl3/RenderStates.h"
#include "fxcc/core/graph/opengl3/IBuffers.h"

using namespace fxcc::graph::opengl3;

fxcc::graph::opengl3::GlfwApp::GlfwApp(const fxcc::platform::common::App::Desc& desc)
	:fxcc::platform::glfw::App(desc)
{
	m_HintMap =
	{
		{GLFW_CONTEXT_VERSION_MAJOR, 4},
		{GLFW_CONTEXT_VERSION_MINOR, 6},
		{GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE},
		{GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE},
	};
};

bool fxcc::graph::opengl3::GlfwApp::Init()
{
	if (!fxcc::platform::glfw::App::Init())
	{
		ztclog::info("Failed init glfw app");
		return false;
	}
	if (!InitGraph())
	{
		ztclog::info("failed init graph");
		return false;
	}

	OnFramebuffersize(m_Desc.m_Size.x, m_Desc.m_Size.y);

	return true;
}

bool fxcc::graph::opengl3::GlfwApp::InitGraph()
{
#ifdef WIN32
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		ztclog::info("Failed to initialize GLAD");
		return false;
	}
#endif // WIN32
	
	fxcc::graph::common::RenderStates::Inst().Init();
	fxcc::graph::opengl3::RenderStates::Inst().Init();
	
	return true;
}

bool GlfwApp::Done()
{
	return glfwWindowShouldClose(m_GlfwWindow);
};

int fxcc::graph::opengl3::GlfwApp::Run()
{
	if(!Init())
	{
		ztclog::info("faield init app");
		return 1;
	}
	while(!Done())
	{
		if (m_Desc.m_Focused)
		{
			glfwPollEvents();

			OnUpdate();

			m_Input.Clear();

			OnFrameRender();

			glfwSwapBuffers(m_GlfwWindow);
		}
	}
	
	OnDestroy();

	return 0;

}

void fxcc::graph::opengl3::GlfwApp::OnDestroy()
{
	fxcc::platform::glfw::App::OnDestroy();
}

void fxcc::graph::opengl3::GlfwApp::OnUpdate()
{
	fxcc::platform::glfw::App::OnUpdate();
}

void fxcc::graph::opengl3::GlfwApp::OnFrameRender()
{
	ztclog::debug("glfw app frameRender");

}

bool fxcc::graph::opengl3::GlfwApp::InitResources()
{
	ztclog::debug("glfw app Init Resources");
	return true;
}

void fxcc::graph::opengl3::GlfwApp::OnFramebuffersize(int w, int h)
{
	m_Desc.m_Size.x = w;
	m_Desc.m_Size.y = h;

	if (w == 0 && h == 0)
	{
		m_Desc.m_Minisize = true;
	}
	else
	{
		m_Desc.m_Minisize = false;
	}
}
